#ifndef SGP4POS_H
#define SGP4POS_H

#include "tle.h"
#include "orbitalelements.h"
#include "eci.h"

namespace libsgp4
{

/**
 * @brief 公开的SGP4类构造函数。
 * 使用给定的TLE（两行元素）数据初始化SGP4对象，并调用Initialise()方法进行初始化。
 * @param tle 包含卫星轨道数据的TLE对象。
 */
class SGP4
{
public:
    explicit SGP4(const Tle& tle)
        : elements_(tle)
    {
        Initialise();
    }
    /**
     * @brief 设置TLE数据。
     * 使用新的TLE数据更新SGP4对象。
     * @param tle 包含新卫星轨道数据的TLE对象。
     */
    void SetTle(const Tle& tle);
    Eci FindPosition(double tsince) const;
    Eci FindPosition(const DateTime& date) const;


private:
    struct CommonConstants
    {
        double cosio;
        double sinio;
        double eta;
        double t2cof;
        double x1mth2;
        double x3thm1;
        double x7thm1;
        double aycof;
        double xlcof;
        double xnodcf;
        double c1;
        double c4;
        double omgdot; // 近地点幅角变化率 (radians/s)
        double xnodot; // 升交点赤经变化率 (radians/s)
        double xmdot;  // 平近点角变化率 (radians/s)
    };

    struct NearSpaceConstants
    {
        double c5;
        double omgcof;
        double xmcof;
        double delmo;
        double sinmo;
        double d2;
        double d3;
        double d4;
        double t3cof;
        double t4cof;
        double t5cof;
    };

    struct DeepSpaceConstants
    {
        double gsto;
        double zmol;
        double zmos;

        /*
         * 月球和太阳在特定历元下的常数
         * 这些常数在DeepSpaceSecular()函数中用于计算长期摄动
         *
         * 在SGP4或其他轨道预测算法中，月球和太阳的引力效应对卫星轨道的长期变化有显著影响。
         * 这些常数通常是通过预先计算好的表格或公式获得的，它们代表了月球和太阳在给定历元下
         * 对卫星轨道产生的摄动效应的大小和方向。
         *
         * DeepSpaceSecular()函数是SGP4算法的一部分，它负责计算这些长期摄动效应，并将它们应用到
         * 卫星的轨道参数上。这些常数作为该函数的输入参数，用于确保计算的准确性。
         */
        double sse;
        double ssi;
        double ssl;
        double ssg;
        double ssh;
        /*
         * 月球和太阳的常数
         * 在DeepSpaceCalculateLunarSolarTerms()函数中用于计算月球和太阳摄动项
         */
        double se2;
        double si2;
        double sl2;
        double sgh2;
        double sh2;
        double se3;
        double si3;
        double sl3;
        double sgh3;
        double sh3;
        double sl4;
        double sgh4;
        double ee2;
        double e3;
        double xi2;
        double xi3;
        double xl2;
        double xl3;
        double xl4;
        double xgh2;
        double xgh3;
        double xgh4;
        double xh2;
        double xh3;
        /*
         * 在DeepSpaceCalcDotTerms()中使用
         */
        double d2201;
        double d2211;
        double d3210;
        double d3222;
        double d4410;
        double d4422;
        double d5220;
        double d5232;
        double d5421;
        double d5433;
        double del1;
        double del2;
        double del3;
        /*
         * 积分器常数
         */
        double xfact;
        double xlamo;

        enum TOrbitShape
        {
            NONE,
            RESONANCE,
            SYNCHRONOUS
        } shape;
    };

    struct IntegratorParams
    {
        /*
         * integrator values
         * 积分器值
         */
        double xli;
        double xni;
        double atime;
    };

    void Initialise();
    static void RecomputeConstants(const double xinc,
                                   double& sinio,
                                   double& cosio,
                                   double& x3thm1,
                                   double& x1mth2,
                                   double& x7thm1,
                                   double& xlcof,
                                   double& aycof);
    Eci FindPositionSDP4(const double tsince) const;
    Eci FindPositionSGP4(double tsince) const;
    static Eci CalculateFinalPositionVelocity(
        const DateTime& date,
        const double e,
        const double a,
        const double omega,
        const double xl,
        const double xnode,
        const double xinc,
        const double xlcof,
        const double aycof,
        const double x3thm1,
        const double x1mth2,
        const double x7thm1,
        const double cosio,
        const double sinio);
    /**
     * Deep space initialisation
     * 深空模型初始化
     */
    void DeepSpaceInitialise(
        const double eosq,
        const double sinio,
        const double cosio,
        const double betao,
        const double theta2,
        const double betao2,
        const double xmdot,
        const double omgdot,
        const double xnodot);
    /**
     * Calculate lunar / solar periodics and apply
     * 计算月/日周期性因素并应用
     */
    static void DeepSpacePeriodics(
        const double tsince,
        const DeepSpaceConstants& ds_constants,
        double& em,
        double& xinc,
        double& omgasm,
        double& xnodes,
        double& xll);
    /**
     * 深空长期影响
     */
    static void DeepSpaceSecular(
        const double tsince,
        const OrbitalElements& elements,
        const CommonConstants& c_constants,
        const DeepSpaceConstants& ds_constants,
        IntegratorParams& integ_params,
        double& xll,
        double& omgasm,
        double& xnodes,
        double& em,
        double& xinc,
        double& xn);

    /**
     * 复位
     */
    void Reset();

    /*
     * 使用的常量
     */
    struct CommonConstants common_consts_;//通用常量
    struct NearSpaceConstants nearspace_consts_;//近地空间常量
    struct DeepSpaceConstants deepspace_consts_;//深空常量
    mutable struct IntegratorParams integrator_params_;//积分器常量

    /*
     * 轨道数据
     */
    OrbitalElements elements_;

    /*
     * flags，标记使用SGP4还是SDP4
     */
    bool use_simple_model_;
    bool use_deep_space_;
};

} // namespace libsgp4

#endif // SGP4POS_H
